package com.ia.aistream.manager.framework.shiro.realm;

import com.google.common.collect.Sets;
import com.ia.aistream.common.exception.user.*;
import com.ia.aistream.manager.authen.ITokenManager;
import com.ia.aistream.manager.authen.token.UserLoginToken;
import com.ia.aistream.manager.framework.shiro.service.SysLoginService;
import com.ia.aistream.manager.framework.util.ShiroUtils;
import com.ia.aistream.manager.system.ISysMenuManager;
import com.ia.aistream.manager.system.ISysRoleManager;
import com.ia.aistream.model.system.entity.SysUser;
import lombok.extern.slf4j.Slf4j;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.*;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;
import org.springframework.beans.factory.annotation.Autowired;

import java.util.HashSet;
import java.util.Set;

/**
 * 自定义Realm 处理登录 权限
 * 
 * @author ia
 */
@Slf4j
public class OpenUserRealm extends AuthorizingRealm
{

    @Autowired
    private SysLoginService loginService;
    @Autowired
    private ITokenManager tokenManager;

    /**
     * 授权
     */
    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection arg0)
    {
        // TODO: 查询用户所属角色
        Set<String> roles = Sets.newLinkedHashSet();
        // TODO: 查询用户权限菜单
        Set<String> permissions = Sets.newLinkedHashSet();

        SimpleAuthorizationInfo authorization = new SimpleAuthorizationInfo();
        authorization.addRoles(roles);
        authorization.addStringPermissions(permissions);
        return authorization;
    }

    /**
     * 登录认证
     */
    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException
    {
        UserLoginToken upToken = (UserLoginToken) token;
        String username = upToken.getUsername();
        String password = "";
        if (upToken.getPassword() != null)
        {
            password = new String(upToken.getPassword());
        }

        SysUser user = null;
        try
        {
            user = loginService.login(username, password);
        }
        catch (CaptchaException e)
        {
            throw new AuthenticationException(e.getMessage(), e);
        }
        catch (UserNotExistsException e)
        {
            throw new UnknownAccountException(e.getMessage(), e);
        }
        catch (UserPasswordNotMatchException e)
        {
            throw new IncorrectCredentialsException(e.getMessage(), e);
        }
        catch (UserPasswordRetryLimitExceedException e)
        {
            throw new ExcessiveAttemptsException(e.getMessage(), e);
        }
        catch (UserBlockedException e)
        {
            throw new LockedAccountException(e.getMessage(), e);
        }
        catch (RoleBlockedException e)
        {
            throw new LockedAccountException(e.getMessage(), e);
        }
        catch (Exception e)
        {
            log.info("对用户[" + username + "]进行登录验证..验证未通过{}", e.getMessage());
            throw new AuthenticationException(e.getMessage(), e);
        }
        SimpleAuthenticationInfo info = new SimpleAuthenticationInfo(user, password, getName());
        //将信息放入redis中,生成tokenKey
        tokenManager.saveToken(upToken.getTokenFrom(), upToken.getTokenId(), user);
        return info;
    }

    /**
     * 清理缓存权限
     */
    public void clearCachedAuthorizationInfo()
    {
        this.clearCachedAuthorizationInfo(SecurityUtils.getSubject().getPrincipals());
    }
}
